<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>柜格编号唯一性验证测试 - Vue版本</title>
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- Vue.js -->
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <!-- Axios -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <style>
        .main-container {
            margin-top: 20px;
        }
        .test-section {
            margin-bottom: 30px;
        }
        .compartment-item {
            border: 1px solid #ddd;
            padding: 10px;
            margin: 5px 0;
            border-radius: 5px;
            background: #f8f9fa;
        }
        .alert-custom {
            margin-top: 15px;
        }
        .form-section {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .test-button {
            margin: 5px;
        }
        .compartment-list {
            max-height: 400px;
            overflow-y: auto;
        }
        .badge-status {
            font-size: 0.8em;
        }
    </style>
</head>
<body>
    <div id="app" class="container main-container">
        <!-- 页面标题 -->
        <div class="row">
            <div class="col-12">
                <h1 class="text-primary">🔒 柜格编号唯一性验证测试</h1>
                <p class="text-muted">基于Vue 3的唯一性验证功能测试工具</p>
                <hr>
            </div>
        </div>

        <!-- 全局消息提示 -->
        <div v-if="message" :class="['alert', messageClass, 'alert-custom']" role="alert">
            {{ message }}
            <button type="button" class="btn-close" @click="clearMessage"></button>
        </div>

        <!-- 当前柜格列表 -->
        <div class="row test-section">
            <div class="col-12">
                <div class="form-section">
                    <h3>📋 当前柜格列表</h3>
                    <div class="d-flex justify-content-between align-items-center mb-3">
                        <button class="btn btn-outline-primary" @click="loadCompartments" :disabled="loading">
                            <span v-if="loading" class="spinner-border spinner-border-sm me-2"></span>
                            {{ loading ? '加载中...' : '刷新列表' }}
                        </button>
                        <span class="text-muted">共 {{ compartments.length }} 个柜格</span>
                    </div>
                    
                    <div class="compartment-list">
                        <div v-if="compartments.length === 0" class="text-center text-muted py-4">
                            暂无柜格数据，点击"刷新列表"加载数据
                        </div>
                        <div v-for="comp in compartments" :key="comp.id" class="compartment-item">
                            <div class="d-flex justify-content-between align-items-center">
                                <div>
                                    <strong>ID:</strong> {{ comp.id }} | 
                                    <strong>编号:</strong> <code>{{ comp.compartmentCode }}</code> | 
                                    <strong>尺寸:</strong> {{ getSizeText(comp.compartmentSize) }}
                                </div>
                                <div>
                                    <span :class="['badge', getStatusClass(comp.compartmentStatus), 'badge-status']">
                                        {{ getStatusText(comp.compartmentStatus) }}
                                    </span>
                                    <small class="text-muted ms-2">
                                        楼层{{ comp.floorNumber }}-位置{{ comp.positionNumber }}
                                    </small>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 测试1: 创建新柜格 -->
        <div class="row test-section">
            <div class="col-12">
                <div class="form-section">
                    <h3>🆕 测试1: 创建新柜格</h3>
                    <div class="row">
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label class="form-label">柜格编号 <span class="text-danger">*</span></label>
                                <input 
                                    type="text" 
                                    class="form-control" 
                                    v-model="createForm.compartmentCode"
                                    placeholder="例如: A001"
                                    :class="{ 'is-invalid': createForm.errors.compartmentCode }"
                                >
                                <div v-if="createForm.errors.compartmentCode" class="invalid-feedback">
                                    {{ createForm.errors.compartmentCode }}
                                </div>
                            </div>
                        </div>
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label class="form-label">柜格尺寸</label>
                                <select class="form-select" v-model="createForm.compartmentSize">
                                    <option value="SMALL">小型</option>
                                    <option value="MEDIUM">中型</option>
                                    <option value="LARGE">大型</option>
                                </select>
                            </div>
                        </div>
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label class="form-label">楼层</label>
                                <input 
                                    type="number" 
                                    class="form-control" 
                                    v-model.number="createForm.floorNumber"
                                    min="1"
                                >
                            </div>
                        </div>
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label class="form-label">位置编号</label>
                                <input 
                                    type="number" 
                                    class="form-control" 
                                    v-model.number="createForm.positionNumber"
                                    min="1"
                                >
                            </div>
                        </div>
                    </div>
                    
                    <div class="d-flex gap-2 flex-wrap">
                        <button 
                            class="btn btn-success test-button" 
                            @click="testCreateCompartment"
                            :disabled="loading"
                        >
                            创建柜格
                        </button>
                        <button 
                            class="btn btn-warning test-button" 
                            @click="testCreateDuplicate"
                            :disabled="loading || compartments.length === 0"
                        >
                            测试重复编号
                        </button>
                        <button 
                            class="btn btn-info test-button" 
                            @click="generateRandomCode"
                        >
                            生成随机编号
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- 测试2: 更新柜格编号 -->
        <div class="row test-section">
            <div class="col-12">
                <div class="form-section">
                    <h3>✏️ 测试2: 更新柜格编号</h3>
                    <div class="row">
                        <div class="col-md-6">
                            <div class="mb-3">
                                <label class="form-label">选择柜格</label>
                                <select 
                                    class="form-select" 
                                    v-model="updateForm.selectedId"
                                    @change="loadCompartmentForEdit"
                                >
                                    <option value="">请选择要编辑的柜格</option>
                                    <option v-for="comp in compartments" :key="comp.id" :value="comp.id">
                                        ID: {{ comp.id }} - {{ comp.compartmentCode }} ({{ getSizeText(comp.compartmentSize) }})
                                    </option>
                                </select>
                            </div>
                        </div>
                        <div class="col-md-6" v-if="updateForm.currentCompartment">
                            <div class="mb-3">
                                <label class="form-label">当前编号</label>
                                <input 
                                    type="text" 
                                    class="form-control" 
                                    :value="updateForm.currentCompartment.compartmentCode"
                                    readonly
                                >
                            </div>
                        </div>
                    </div>

                    <div v-if="updateForm.currentCompartment" class="border-top pt-3">
                        <h5>编辑柜格信息</h5>
                        <div class="row">
                            <div class="col-md-6">
                                <div class="mb-3">
                                    <label class="form-label">新编号 <span class="text-danger">*</span></label>
                                    <input 
                                        type="text" 
                                        class="form-control" 
                                        v-model="updateForm.compartmentCode"
                                        placeholder="输入新的柜格编号"
                                        :class="{ 'is-invalid': updateForm.errors.compartmentCode }"
                                    >
                                    <div v-if="updateForm.errors.compartmentCode" class="invalid-feedback">
                                        {{ updateForm.errors.compartmentCode }}
                                    </div>
                                </div>
                            </div>
                            <div class="col-md-6">
                                <div class="mb-3">
                                    <label class="form-label">柜格尺寸</label>
                                    <select class="form-select" v-model="updateForm.compartmentSize">
                                        <option value="SMALL">小型</option>
                                        <option value="MEDIUM">中型</option>
                                        <option value="LARGE">大型</option>
                                    </select>
                                </div>
                            </div>
                        </div>
                        
                        <div class="d-flex gap-2 flex-wrap">
                            <button 
                                class="btn btn-primary test-button" 
                                @click="testUpdateCompartment"
                                :disabled="loading"
                            >
                                更新柜格
                            </button>
                            <button 
                                class="btn btn-warning test-button" 
                                @click="testUpdateToDuplicate"
                                :disabled="loading || compartments.length < 2"
                            >
                                测试更新为重复编号
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 测试3: 边界情况测试 -->
        <div class="row test-section">
            <div class="col-12">
                <div class="form-section">
                    <h3>🧪 测试3: 边界情况测试</h3>
                    <p class="text-muted">测试各种特殊情况下的验证行为</p>
                    
                    <div class="d-flex gap-2 flex-wrap">
                        <button 
                            class="btn btn-outline-danger test-button" 
                            @click="testEmptyCode"
                            :disabled="loading"
                        >
                            测试空编号
                        </button>
                        <button 
                            class="btn btn-outline-danger test-button" 
                            @click="testSpaceCode"
                            :disabled="loading"
                        >
                            测试空格编号
                        </button>
                        <button 
                            class="btn btn-outline-warning test-button" 
                            @click="testSpecialChars"
                            :disabled="loading"
                        >
                            测试特殊字符
                        </button>
                        <button 
                            class="btn btn-outline-info test-button" 
                            @click="testLongCode"
                            :disabled="loading"
                        >
                            测试长编号
                        </button>
                        <button 
                            class="btn btn-outline-secondary test-button" 
                            @click="testTrimming"
                            :disabled="loading"
                        >
                            测试空格处理
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- 测试结果统计 -->
        <div class="row test-section">
            <div class="col-12">
                <div class="form-section">
                    <h3>📊 测试结果统计</h3>
                    <div class="row">
                        <div class="col-md-3">
                            <div class="text-center">
                                <h4 class="text-success">{{ testStats.success }}</h4>
                                <small class="text-muted">成功测试</small>
                            </div>
                        </div>
                        <div class="col-md-3">
                            <div class="text-center">
                                <h4 class="text-danger">{{ testStats.failed }}</h4>
                                <small class="text-muted">失败测试</small>
                            </div>
                        </div>
                        <div class="col-md-3">
                            <div class="text-center">
                                <h4 class="text-info">{{ testStats.total }}</h4>
                                <small class="text-muted">总测试数</small>
                            </div>
                        </div>
                        <div class="col-md-3">
                            <div class="text-center">
                                <button class="btn btn-sm btn-outline-secondary" @click="resetStats">
                                    重置统计
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    
    <script>
        const { createApp } = Vue;

        createApp({
            data() {
                return {
                    loading: false,
                    message: '',
                    messageClass: '',
                    compartments: [],
                    createForm: {
                        compartmentCode: '',
                        compartmentSize: 'SMALL',
                        floorNumber: 1,
                        positionNumber: 1,
                        errors: {}
                    },
                    updateForm: {
                        selectedId: '',
                        currentCompartment: null,
                        compartmentCode: '',
                        compartmentSize: 'SMALL',
                        errors: {}
                    },
                    testStats: {
                        success: 0,
                        failed: 0,
                        total: 0
                    }
                }
            },
            
            mounted() {
                this.loadCompartments();
                this.setupAxiosInterceptors();
            },
            
            methods: {
                // 设置Axios拦截器
                setupAxiosInterceptors() {
                    axios.defaults.headers.common['Authorization'] = 'Bearer admin-token';
                },
                
                // 显示消息
                showMessage(message, isSuccess = true) {
                    this.message = message;
                    this.messageClass = isSuccess ? 'alert-success' : 'alert-danger';
                    
                    // 更新统计
                    this.testStats.total++;
                    if (isSuccess) {
                        this.testStats.success++;
                    } else {
                        this.testStats.failed++;
                    }
                    
                    // 3秒后自动清除消息
                    setTimeout(() => {
                        this.clearMessage();
                    }, 3000);
                },
                
                // 清除消息
                clearMessage() {
                    this.message = '';
                    this.messageClass = '';
                },
                
                // 加载柜格列表
                async loadCompartments() {
                    this.loading = true;
                    try {
                        const response = await axios.get('/api/compartments/all');
                        if (response.data.success) {
                            this.compartments = response.data.data;
                            this.showMessage(`成功加载 ${this.compartments.length} 个柜格`, true);
                        } else {
                            this.showMessage(`加载失败: ${response.data.message}`, false);
                        }
                    } catch (error) {
                        this.showMessage(`网络错误: ${error.message}`, false);
                    } finally {
                        this.loading = false;
                    }
                },
                
                // 创建柜格测试
                async testCreateCompartment() {
                    this.clearFormErrors('create');
                    
                    if (!this.createForm.compartmentCode.trim()) {
                        this.createForm.errors.compartmentCode = '柜格编号不能为空';
                        return;
                    }
                    
                    this.loading = true;
                    try {
                        const compartment = {
                            compartmentCode: this.createForm.compartmentCode,
                            compartmentSize: this.createForm.compartmentSize,
                            floorNumber: this.createForm.floorNumber,
                            positionNumber: this.createForm.positionNumber
                        };
                        
                        const response = await axios.post('/api/compartments', compartment);
                        
                        if (response.data.success) {
                            this.showMessage(`✅ ${response.data.message}`, true);
                            this.loadCompartments();
                            this.resetCreateForm();
                        } else {
                            this.showMessage(`❌ ${response.data.message}`, false);
                        }
                    } catch (error) {
                        this.showMessage(`❌ 网络错误: ${error.message}`, false);
                    } finally {
                        this.loading = false;
                    }
                },
                
                // 测试重复编号
                async testCreateDuplicate() {
                    if (this.compartments.length === 0) {
                        this.showMessage('❌ 请先加载柜格列表', false);
                        return;
                    }
                    
                    const existingCode = this.compartments[0].compartmentCode;
                    this.createForm.compartmentCode = existingCode;
                    this.showMessage(`🔄 准备测试重复编号: ${existingCode}`, true);
                    
                    setTimeout(() => {
                        this.testCreateCompartment();
                    }, 1000);
                },
                
                // 生成随机编号
                generateRandomCode() {
                    const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
                    const numbers = '0123456789';
                    const letter = letters[Math.floor(Math.random() * letters.length)];
                    const number = String(Math.floor(Math.random() * 1000)).padStart(3, '0');
                    this.createForm.compartmentCode = letter + number;
                },
                
                // 加载柜格用于编辑
                async loadCompartmentForEdit() {
                    if (!this.updateForm.selectedId) {
                        this.updateForm.currentCompartment = null;
                        return;
                    }
                    
                    this.loading = true;
                    try {
                        const response = await axios.get(`/api/compartments/${this.updateForm.selectedId}`);
                        if (response.data.success) {
                            this.updateForm.currentCompartment = response.data.data;
                            this.updateForm.compartmentCode = response.data.data.compartmentCode;
                            this.updateForm.compartmentSize = response.data.data.compartmentSize;
                            this.clearFormErrors('update');
                        } else {
                            this.showMessage(`❌ ${response.data.message}`, false);
                        }
                    } catch (error) {
                        this.showMessage(`❌ 网络错误: ${error.message}`, false);
                    } finally {
                        this.loading = false;
                    }
                },
                
                // 更新柜格测试
                async testUpdateCompartment() {
                    this.clearFormErrors('update');
                    
                    if (!this.updateForm.compartmentCode.trim()) {
                        this.updateForm.errors.compartmentCode = '柜格编号不能为空';
                        return;
                    }
                    
                    this.loading = true;
                    try {
                        const compartment = {
                            compartmentCode: this.updateForm.compartmentCode,
                            compartmentSize: this.updateForm.compartmentSize
                        };
                        
                        const response = await axios.put(`/api/compartments/${this.updateForm.selectedId}`, compartment);
                        
                        if (response.data.success) {
                            this.showMessage(`✅ ${response.data.message}`, true);
                            this.loadCompartments();
                            this.loadCompartmentForEdit(); // 刷新编辑表单
                        } else {
                            this.showMessage(`❌ ${response.data.message}`, false);
                        }
                    } catch (error) {
                        this.showMessage(`❌ 网络错误: ${error.message}`, false);
                    } finally {
                        this.loading = false;
                    }
                },
                
                // 测试更新为重复编号
                async testUpdateToDuplicate() {
                    if (this.compartments.length < 2) {
                        this.showMessage('❌ 需要至少2个柜格才能测试重复编号', false);
                        return;
                    }
                    
                    const currentId = parseInt(this.updateForm.selectedId);
                    const duplicateCode = this.compartments.find(c => c.id !== currentId)?.compartmentCode;
                    
                    if (duplicateCode) {
                        this.updateForm.compartmentCode = duplicateCode;
                        this.showMessage(`🔄 准备测试重复编号: ${duplicateCode}`, true);
                        
                        setTimeout(() => {
                            this.testUpdateCompartment();
                        }, 1000);
                    } else {
                        this.showMessage('❌ 找不到其他柜格编号用于测试', false);
                    }
                },
                
                // 边界情况测试
                async testEmptyCode() {
                    await this.testEdgeCase('', '空编号测试');
                },
                
                async testSpaceCode() {
                    await this.testEdgeCase('   ', '空格编号测试');
                },
                
                async testSpecialChars() {
                    await this.testEdgeCase('!@#$%^&*()', '特殊字符测试');
                },
                
                async testLongCode() {
                    await this.testEdgeCase('A'.repeat(100), '长编号测试');
                },
                
                async testTrimming() {
                    await this.testEdgeCase('  A001  ', '空格处理测试');
                },
                
                // 边界情况测试通用方法
                async testEdgeCase(code, testName) {
                    this.loading = true;
                    try {
                        const compartment = {
                            compartmentCode: code,
                            compartmentSize: 'SMALL',
                            floorNumber: 1,
                            positionNumber: 1
                        };
                        
                        const response = await axios.post('/api/compartments', compartment);
                        
                        if (response.data.success) {
                            this.showMessage(`✅ ${testName}: ${response.data.message}`, true);
                            this.loadCompartments();
                        } else {
                            this.showMessage(`❌ ${testName}: ${response.data.message}`, false);
                        }
                    } catch (error) {
                        this.showMessage(`❌ ${testName} 网络错误: ${error.message}`, false);
                    } finally {
                        this.loading = false;
                    }
                },
                
                // 辅助方法
                getSizeText(size) {
                    const sizeMap = {
                        'SMALL': '小型',
                        'MEDIUM': '中型',
                        'LARGE': '大型'
                    };
                    return sizeMap[size] || size;
                },
                
                getStatusText(status) {
                    const statusMap = {
                        'AVAILABLE': '可用',
                        'OCCUPIED': '占用',
                        'MAINTENANCE': '维护'
                    };
                    return statusMap[status] || status;
                },
                
                getStatusClass(status) {
                    const classMap = {
                        'AVAILABLE': 'bg-success',
                        'OCCUPIED': 'bg-danger',
                        'MAINTENANCE': 'bg-warning'
                    };
                    return classMap[status] || 'bg-secondary';
                },
                
                clearFormErrors(formType) {
                    if (formType === 'create') {
                        this.createForm.errors = {};
                    } else if (formType === 'update') {
                        this.updateForm.errors = {};
                    }
                },
                
                resetCreateForm() {
                    this.createForm.compartmentCode = '';
                    this.createForm.compartmentSize = 'SMALL';
                    this.createForm.floorNumber = 1;
                    this.createForm.positionNumber = 1;
                    this.createForm.errors = {};
                },
                
                resetStats() {
                    this.testStats = {
                        success: 0,
                        failed: 0,
                        total: 0
                    };
                    this.showMessage('📊 测试统计已重置', true);
                }
            }
        }).mount('#app');
    </script>
</body>
</html>